﻿using B.S.BaseData.Domain.Entities.RBAC;
using B.S.BaseData.Domain.OrmTest;
using Microsoft.AspNetCore.Http;
using Microsoft.Data.SqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace B.S.BaseData.Infrastructure.Helper
{

    #region 添加
    /* /// <summary>
     /// 自定义orm 利用反射封装增删改查
     /// </summary>
     public class OrmHelper<T>
     {
         private readonly string conStr;
         *//*private readonly IHttpContextAccessor httpContextAccessor;*//*

         public OrmHelper(string conStr*//*, IHttpContextAccessor _httpContextAccessor*//*)
         {
             this.conStr = conStr;
             *//*httpContextAccessor = _httpContextAccessor;*//*
         }
         /// <summary>
         /// 添加
         /// </summary>
         /// <param name="entity"></param>
         /// <returns></returns>
         public int Add(T entity)
         {
             using (SqlConnection conn = new SqlConnection(conStr))
             {
                 conn.Open();

                 Type type = typeof(T);

                 var entityProps = type.GetProperties().Where(x => !x.GetCustomAttributes(typeof(OrmKeyAttribute), false).Any());

                 string fields = string.Join(",", entityProps.Select(x => x.Name));

                 string fieldsParams = string.Join(",", entityProps.Select(x => $"@{x.Name}"));

                 var tableAttribute = type.GetCustomAttribute<OrmTableAttribute>();

                 string TableName = type.Name;

                 if(tableAttribute != null)
                 {
                     TableName = tableAttribute.tableName;
                 }

                 string sql = $"INSERT INTO {TableName} ({fields}) VALUES ({fieldsParams})";

                 SqlCommand cmd = new SqlCommand(sql, conn);

                *//* var claims = httpContextAccessor.HttpContext?.User?.Claims;
                 int userId = Convert.ToInt32(claims?.FirstOrDefault(x => x.Type == "UserId")?.Value ?? "0");
                 var userName = claims?.FirstOrDefault(x => x.Type == "UserName")?.Value ?? "系统";
                 var time = DateTime.Now;*//*
                 foreach (var prop in entityProps)
                 {
                     if(prop.Name.Equals("AddId", StringComparison.OrdinalIgnoreCase))
                     {
                         prop.SetValue(entity, 1);
                     }
                     if (prop.Name.Equals("AddName", StringComparison.OrdinalIgnoreCase))
                     {
                         prop.SetValue(entity, "admin");
                     }
                     if (prop.Name.Equals("AddTime", StringComparison.OrdinalIgnoreCase))
                     {
                         prop.SetValue(entity, DateTime.Now);
                     }
                     if (prop.Name.Equals("IsDelete", StringComparison.OrdinalIgnoreCase))
                     {
                         prop.SetValue(entity, false);
                     }

                     var value = prop.GetValue(entity);
                     if (value == null)
                     {
                         cmd.Parameters.AddWithValue($"@{prop.Name}", DBNull.Value);
                     }
                     else
                     {
                         cmd.Parameters.AddWithValue($"@{prop.Name}", value);
                     }
                 }

                 return cmd.ExecuteNonQuery();
             }
         }
    }
     }*/
    #endregion


    public class OrmHelper<T> where T : class, new()
    {
        private readonly string conStr;

        public OrmHelper(string conStr)
        {
            this.conStr = conStr;
        }

        /// <summary>
        /// 获取表名
        /// </summary>
        private string GetTableName()
        {
            Type type = typeof(T);
            var tableAttribute = type.GetCustomAttribute<OrmTableAttribute>();
            return tableAttribute?.tableName ?? type.Name;
        }

        /// <summary>
        /// 获取主键属性
        /// </summary>
        private PropertyInfo GetKeyProperty()
        {
            return typeof(T).GetProperties()
                .FirstOrDefault(x => x.GetCustomAttributes(typeof(OrmKeyAttribute), false).Any())
                ?? throw new Exception("未找到主键标识");
        }

        /// <summary>
        /// 获取实体属性（排除主键）
        /// </summary>
        private IEnumerable<PropertyInfo> GetEntityProperties()
        {
            return typeof(T).GetProperties()
                .Where(x => !x.GetCustomAttributes(typeof(OrmKeyAttribute), false).Any());
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public int Add(T entity)
        {
            using (SqlConnection conn = new SqlConnection(conStr))
            {
                conn.Open();

                Type type = typeof(T);

                var entityProps = GetEntityProperties();

                string fields = string.Join(",", entityProps.Select(x => x.Name));

                string fieldsParams = string.Join(",", entityProps.Select(x => $"@{x.Name}"));

                var tableAttribute = type.GetCustomAttribute<OrmTableAttribute>();

                string TableName = type.Name;

                if (tableAttribute != null)
                {
                    TableName = tableAttribute.tableName;
                }

                string sql = $"INSERT INTO {TableName} ({fields}) VALUES ({fieldsParams})";

                SqlCommand cmd = new SqlCommand(sql, conn);
/*
                //* var claims = httpContextAccessor.HttpContext?.User?.Claims;
                 int userId = Convert.ToInt32(claims?.FirstOrDefault(x => x.Type == "UserId")?.Value ?? "0");
                var userName = claims?.FirstOrDefault(x => x.Type == "UserName")?.Value ?? "系统";
                var time = DateTime.Now; //**/
                 foreach (var prop in entityProps)
                {
                    if (prop.Name.Equals("AddId", StringComparison.OrdinalIgnoreCase))
                    {
                        prop.SetValue(entity, 1);
                    }
                    if (prop.Name.Equals("AddName", StringComparison.OrdinalIgnoreCase))
                    {
                        prop.SetValue(entity, "admin");
                    }
                    if (prop.Name.Equals("AddTime", StringComparison.OrdinalIgnoreCase))
                    {
                        prop.SetValue(entity, DateTime.Now);
                    }
                    if (prop.Name.Equals("IsDelete", StringComparison.OrdinalIgnoreCase))
                    {
                        prop.SetValue(entity, false);
                    }

                    var value = prop.GetValue(entity);
                    if (value == null)
                    {
                        cmd.Parameters.AddWithValue($"@{prop.Name}", DBNull.Value);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue($"@{prop.Name}", value);
                    }
                }

                return cmd.ExecuteNonQuery();
            }
        }

        /// <summary>
        /// 查询所有数据
        /// </summary>
        public async Task<IEnumerable<T>> GetAll()
        {
            using var conn = new SqlConnection(conStr);
            await conn.OpenAsync();

            string tableName = GetTableName();
            string sql = $"SELECT * FROM {tableName} WHERE IsDelete = 0";

            using var cmd = new SqlCommand(sql, conn);
            using var reader = await cmd.ExecuteReaderAsync();

            var list = new List<T>();
            while (await reader.ReadAsync())
            {
                var entity = new T();
                foreach (var prop in typeof(T).GetProperties())
                {
                    if (!reader.IsDBNull(reader.GetOrdinal(prop.Name)))
                    {
                        prop.SetValue(entity, reader[prop.Name]);
                    }
                }
                list.Add(entity);
            }
            return list;
        }

        /// <summary>
        /// 根据ID查询
        /// </summary>
        public async Task<T> GetById(object id)
        {
            using var conn = new SqlConnection(conStr);
            await conn.OpenAsync();

            string tableName = GetTableName();
            var keyProp = GetKeyProperty();
            string sql = $"SELECT * FROM {tableName} WHERE {keyProp.Name} = @Id AND IsDelete = 0";

            using var cmd = new SqlCommand(sql, conn);
            cmd.Parameters.AddWithValue("@Id", id);

            using var reader = await cmd.ExecuteReaderAsync();
            if (await reader.ReadAsync())
            {
                var entity = new T();
                foreach (var prop in typeof(T).GetProperties())
                {
                    if (!reader.IsDBNull(reader.GetOrdinal(prop.Name)))
                    {
                        prop.SetValue(entity, reader[prop.Name]);
                    }
                }
                return entity;
            }
            return null;
        }

        /// <summary>
        /// 修改数据
        /// </summary>
        public async Task<int> Update(T entity)
        {
            using var conn = new SqlConnection(conStr);
            await conn.OpenAsync();

            var type = typeof(T);
            var keyProp = GetKeyProperty();
            var entityProps = GetEntityProperties();

            string setClause = string.Join(",", entityProps.Select(x => $"{x.Name}=@{x.Name}"));
            string tableName = GetTableName();
            string sql = $"UPDATE {tableName} SET {setClause}, UpdateId=@UpdateId, UpdateName=@UpdateName, UpdateTime=@UpdateTime WHERE {keyProp.Name}=@{keyProp.Name}";

            using var cmd = new SqlCommand(sql, conn);

            // 设置审计字段
            cmd.Parameters.AddWithValue("@UpdateId", 1); // 实际应从用户上下文获取
            cmd.Parameters.AddWithValue("@UpdateName", "admin");
            cmd.Parameters.AddWithValue("@UpdateTime", DateTime.Now);

            // 设置实体字段值
            foreach (var prop in entityProps)
            {
                var value = prop.GetValue(entity);
                cmd.Parameters.AddWithValue($"@{prop.Name}", value ?? DBNull.Value);
            }
            cmd.Parameters.AddWithValue($"@{keyProp.Name}", keyProp.GetValue(entity));

            return await cmd.ExecuteNonQueryAsync();
        }

        /// <summary>
        /// 删除数据（软删除）
        /// </summary>
        public async Task<int> Delete(object id)
        {
            using var conn = new SqlConnection(conStr);
            await conn.OpenAsync();

            string tableName = GetTableName();
            var keyProp = GetKeyProperty();
            string sql = $"UPDATE {tableName} SET IsDelete=1, DeleteId=@DeleteId, DeleteName=@DeleteName, DeleteTime=@DeleteTime WHERE {keyProp.Name}=@Id";

            using var cmd = new SqlCommand(sql, conn);
            cmd.Parameters.AddWithValue("@Id", id);
            cmd.Parameters.AddWithValue("@DeleteId", 1); // 实际应从用户上下文获取
            cmd.Parameters.AddWithValue("@DeleteName", "admin");
            cmd.Parameters.AddWithValue("@DeleteTime", DateTime.Now);

            return await cmd.ExecuteNonQueryAsync();
        }
    }


}